﻿Public Class Cypher

    Public image1 As New ImageDitherer()
    Public image2 As New ImageDitherer()
    Public image3 As New ImageDitherer()

    Public width As Integer = 0
    Public height As Integer = 0

    Public encoded1 As New ImageHolder()
    Public encoded2 As New ImageHolder()
    Public encoded1Thumb As New ImageHolder()
    Public encoded2Thumb As New ImageHolder()

    Public sectionProcessor As New List(Of blockProcessorClass)
    Public batchSize As Integer = 3000
    Public pixelCount As Integer = 0

    Public Sub New(ByVal bitmap1 As Bitmap, ByVal bitmap2 As Bitmap, ByVal bitmap3 As Bitmap, ByVal filter1 As SelectedSettings, ByVal filter2 As SelectedSettings, ByVal filter3 As SelectedSettings)
        width = bitmap1.Width
        height = bitmap1.Height
        image1.setDither(filter1)
        image2.setDither(filter2)
        image3.setDither(filter3)
        setImage1(bitmap1)
        setImage2(bitmap2)
        setImage3(bitmap3)
    End Sub

    Public Sub setImage1(ByVal bitmap1 As Bitmap)
        width = bitmap1.Width
        height = bitmap1.Height
        image1.setImageAndSize(bitmap1, width, height)
        image2.setSize(width, height)
        image3.setSize(width, height)
        encoded1Thumb = New Bitmap(image1.standardisedBitmapThumb.Width * 2, image1.standardisedBitmapThumb.Height * 2)
        encoded2Thumb = New Bitmap(image1.standardisedBitmapThumb.Width * 2, image1.standardisedBitmapThumb.Height * 2)
        makeSmallSize()
    End Sub

    Public Sub setImage2(ByVal bitmap2 As Bitmap)
        image2.setImageAndSize(bitmap2, width, height)
        makeSmallSize()
    End Sub

    Public Sub setImage3(ByVal bitmap3 As Bitmap)
        image3.setImageAndSize(bitmap3, width, height)
        makeSmallSize()
    End Sub

    Public Sub makeSmallSize()
        If image1.originalBitmap IsNot Nothing And image2.originalBitmap IsNot Nothing And image3.originalBitmap IsNot Nothing Then
            createEncodedImages(
                image1.ditheredBitmapThumbForProcessing,
                image2.ditheredBitmapThumbForProcessing,
                image3.ditheredBitmapThumbForProcessing,
                encoded1Thumb,
                encoded2Thumb)
        End If
    End Sub

    Public Sub makeFullSize()
        If image1.originalBitmap IsNot Nothing And image2.originalBitmap IsNot Nothing And image3.originalBitmap IsNot Nothing Then
            encoded1 = New Bitmap(image1.standardisedBitmap.Width * 2, image1.standardisedBitmap.Height * 2)
            encoded2 = New Bitmap(image1.standardisedBitmap.Width * 2, image1.standardisedBitmap.Height * 2)
            createEncodedImages(
                image1.ditheredBitmap,
                image2.ditheredBitmap,
                image3.ditheredBitmap,
                encoded1,
                encoded2)
        End If
    End Sub

    Public Sub createEncodedImages(ByVal image1 As ImageHolder, ByVal image2 As ImageHolder, ByVal image3 As ImageHolder,
                                   ByVal encoded1 As ImageHolder, ByVal encoded2 As ImageHolder)
        Dim blockTotal As Integer = 0
        Dim startIndex As Integer = 0
        Dim endindex As Integer = 0
        Dim proc As blockProcessorClass = Nothing
        sectionProcessor.Clear()
        pixelCount = image1.bitmap.Width * image1.bitmap.Height
        If pixelCount > batchSize Then
            blockTotal = pixelCount \ batchSize
            startIndex = 0
            endindex = batchSize - 1 ' 0 based.
            While (sectionProcessor.Count < blockTotal)
                proc = New blockProcessorClass(image1, image2, image3, encoded1, encoded2, startIndex, endindex)
                sectionProcessor.Add(proc)
                startIndex += batchSize
                endindex += batchSize
            End While
            proc = New blockProcessorClass(image1, image2, image3, encoded1, encoded2, startIndex, pixelCount - 1)
            sectionProcessor.Add(proc)
        End If
        image1.LockBitmap(Imaging.ImageLockMode.ReadWrite)
        image2.lockBitmap(Imaging.ImageLockMode.ReadWrite)
        image3.lockBitmap(Imaging.ImageLockMode.ReadWrite)
        encoded1.lockBitmap(Imaging.ImageLockMode.ReadWrite)
        encoded2.lockBitmap(Imaging.ImageLockMode.ReadWrite)
        System.Threading.Tasks.Parallel.[For](0, sectionProcessor.Count, New Action(Of Integer)(AddressOf runUpdateBlockThread))
        'For i As Integer = 0 To blockListIndex
        '   processThread(i)
        'Next
        image1.unlockBitmap()
        image2.unlockBitmap()
        image3.unlockBitmap()
        encoded1.unlockBitmap()
        encoded2.unlockBitmap()
    End Sub

    Public Sub runUpdateBlockThread(ByVal i As Integer)
        sectionProcessor(i).updateRange()
    End Sub

End Class
